package com.info3k.client.components;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.info3k.client.Info3K;
import com.info3k.client.domain.Category;
import com.info3k.client.domain.Location;
import com.info3k.client.utils.ToolsClient;

public class LocationListWithSearch extends Composite {

	private TextBox filterBox = new TextBox();
	private Button filterButton = new Button(Info3K.msgs.search());
	
	private HorizontalPanel panel1 = new HorizontalPanel();
	private VerticalPanel panel2 = new VerticalPanel();
	
	private boolean selectable = false;
	
	private List<LocationRenderer> locationRenderers;
	
	private ListBox category = new ListBox();
	
	private List<Category> categories;
	
	private Info3K info3k;
	
	private Pagination pagination = new Pagination(10);
	
	private String filterText;

	public LocationListWithSearch(boolean selectable, Info3K info, final Category cat, final String searchTerm, String cHeight, Location[] locations){
		this.info3k = info;
		this.selectable = selectable;
		VerticalPanel panel = new VerticalPanel();
		initWidget(panel);
		panel.setWidth("100%");
		
		category.setWidth("200px");
		
		panel.add(panel1);
		panel.setCellWidth(panel1, "100%");
		panel1.setWidth("100%");
		panel.add(new HTML("<div class=\"h_line\"></div>"));
		panel.add(pagination);
		panel.add(new HTML("<div class=\"h_line\"></div>"));
		panel.setCellHorizontalAlignment(pagination, VerticalPanel.ALIGN_RIGHT);
		panel2.setWidth("100%");
		
		if(selectable){
			ScrollPanel scroll = new ScrollPanel(panel2);
			scroll.setHeight("350px");
			panel.add(scroll);
			panel.setCellWidth(scroll, "100%");
		} else {
			panel.add(panel2);
			panel.setCellWidth(panel2, "100%");
		}
		
		filterBox.setWidth("95%");
		panel1.add(filterBox);
		panel1.add(category);
		panel1.add(filterButton);
		panel1.setCellWidth(filterBox, "55%");
		panel1.setCellWidth(category, "185px");
		panel1.setCellWidth(filterButton, "10%");
		
		Info3K.loader.setVisible(true);
		Info3K.infoService.getAllCategories(new AsyncCallback<List<Category>>(){
			public void onFailure(Throwable caught) {
				Info3K.loader.setVisible(false);
				InfoWindow.showMessage(Info3K.msgs.error(), caught.getMessage());
			}

			public void onSuccess(List<Category> result) {
				Info3K.loader.setVisible(false);
				categories = result;
				if(categories!=null){
					category.addItem("All", "ALL");
					for (Category cat : categories) {
						category.addItem(cat.getName(), cat.getCode());
					}
					if(cat!=null || searchTerm!=null){
						filterBox.setText(searchTerm);
						if(cat!=null){
							Integer index = getIndexByCategoryCode(cat.getCode());
							if(index!=null){
								category.setSelectedIndex(index);
								filterButton.click();
							}
						} else {
							filterButton.click();
						}
					}
				}
			}
		});
		
		filterButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				filterText = filterBox.getText();
				callService(filterBox.getText(), pagination.getPageSize(), null);
			}
		});
		
		if(locations!=null) {
			renderLocations(ToolsClient.fromArrayToCollection(locations), true);
		}
		
		pagination.addValueChangeHandler(new ValueChangeHandler<Integer>(){
			public void onValueChange(ValueChangeEvent<Integer> event) {
				callService(filterText, pagination.getPageSize(), event.getValue());
			}
		});
	}
	
	private void callService(String filter, Integer pageSize, Integer current){
		Info3K.loader.setVisible(true);
		Info3K.infoService.getLocationsByFilter(filter, getCategoryByCode(category.getValue(category.getSelectedIndex())), pageSize, current, new AsyncCallback<List<Location>>(){
			public void onFailure(Throwable caught) {
				Info3K.loader.setVisible(false);
				InfoWindow.showMessage(Info3K.msgs.error(), caught.getMessage());
			}

			public void onSuccess(List<Location> result) {
				Info3K.loader.setVisible(false);
				if(result.size()>0 && result.get(0).getLength()!=null){
					pagination.setLength(result.get(0).getLength());
					pagination.render(0);
				}
				renderLocations(result, false);
			}
		});

	}
	
	private Category getCategoryByCode(String code){
		for (Category cat : categories) {
			if(cat.getCode().equals(code)) {
				if(cat.getCode().equals("ALL")) return null;
				return cat;
			}
		}
		return null;
	}
	
	private Integer getIndexByCategoryCode(String code){
		for (int i = 0; i < category.getItemCount(); i++) {
			if(category.getValue(i).equals(code)) return i; 
		}
		return null;
	}
	
	private void renderLocations(List<Location> locations, boolean checked){
		panel2.clear();
		if(locationRenderers!=null){
			
			List<LocationRenderer> tempList = new ArrayList<LocationRenderer>();
			for (LocationRenderer locationR : locationRenderers) {
				if(locationR.isLocationSelected()){
					LocationRenderer rend = new LocationRenderer(locationR.getLocation(), selectable, info3k);
					rend.clickCheckbox();
					panel2.add(rend);
					panel2.add(new HTML("<hr>"));
					tempList.add(rend);		
				}
			}
			locationRenderers = tempList;
		}
		if(locationRenderers==null) locationRenderers = new ArrayList<LocationRenderer>();
		for (Location location : locations) {
			LocationRenderer rend = new LocationRenderer(location, selectable, info3k);
			rend.selected.setValue(checked);
			rend.setLocationSelected(checked);
			if(checked) rend.clickCheckbox();
			if(!containsLocationRenderer(locationRenderers, rend)){
				locationRenderers.add(rend);
				panel2.add(rend);
				panel2.add(new HTML("<hr>"));
			}
		}
		if(locations.size()==0) panel2.add(new HTML(Info3K.msgs.noLocationsFound()));
	}
	
	private Boolean containsLocationRenderer(List<LocationRenderer> list, LocationRenderer rend){
		for (LocationRenderer locationRenderer : list) {
			if(rend.getLocation().getLocationName().equals(locationRenderer.getLocation().getLocationName()) && rend.getLocation().getId().equals(locationRenderer.getLocation().getId())){
				return true;
			}
		}
		return false;
	}
	
	public List<LocationRenderer> getLocationRenderers() {
		return locationRenderers;
	}

	public void setLocationRenderers(List<LocationRenderer> locationRenderers) {
		this.locationRenderers = locationRenderers;
	}
}
